<script setup lang="tsx">
import { Form, FormSchema } from '@/components/Form'
import { PropType, reactive, ref } from 'vue'
import { useValidator } from '@/hooks/web/useValidator'
import {
  SysDictDetailVo,
  SysDictEditQo,
  SysDictListVo,
  SysDictSearchQo
} from '@/api/system/dict/SysDict/types'
import { isBlank } from '@/utils/StringUtils'
import { useBaseWriteView } from '@/base/views/BaseWriteView'
// [[ OnflowGenerator Range (- selectFunctionImport -) Start ]]
import {
  selectSysDictNameListApi,
  sysDictAddApi,
  sysDictChildrenListApi,
  sysDictDeleteApi,
  sysDictUpdateApi
} from '@/api/system/dict/SysDict'
import { KeyLabelValueVo } from '@/base/api/KeyLabelValueVo'
import {
  ElButton,
  ElDialog,
  ElInput,
  ElMessage,
  ElMessageBox,
  ElTable,
  ElTableColumn,
  ElText
} from 'element-plus'
import { BaseDeleteQo } from '@/base/api/BaseQo'
// [[ OnflowGenerator Range (- selectFunctionImport -) End ]]

const { required } = useValidator()

const props = defineProps({
  currentRow: {
    type: Object as PropType<Nullable<SysDictDetailVo>>,
    default: () => null
  },
  editType: {
    type: String,
    default: 'add'
  },
  editId: {
    type: Number,
    default: -1
  }
})
const isAdd = ref(props.editType === 'add')

const { formRegister, submit, doWatch } = useBaseWriteView(props)
doWatch()

const formRef = ref<typeof Form>()
// [[ OnflowGenerator Range (- dictFunctions -) Start ]]

// [[ OnflowGenerator Range (- dictFunctions -) End ]]

// [[ OnflowGenerator Range (- selectFunctions -) Start ]]
const sysDictNameList = ref<Array<KeyLabelValueVo>>([])
const getSysDictNameList = async () => {
  const res = await selectSysDictNameListApi({})
  sysDictNameList.value = res.data
}
getSysDictNameList()

// [[ OnflowGenerator Range (- selectFunctions -) End ]]

const schema = reactive<FormSchema[]>([
  // [[ OnflowGenerator Range (- inputSchema -) Start ]]
  {
    field: 'code',
    label: '字典码(数字/英文)',
    component: 'Input',
    componentProps: {
      placeholder: '请输入字典码',
      clearable: true
    }
  },
  {
    field: 'name',
    label: '字典值',
    component: 'Input',
    componentProps: {
      placeholder: '请输入字典值',
      clearable: true
    }
  },
  {
    field: 'codePath',
    label: '字典码路径',
    remove: isAdd.value,
    component: 'Input',
    componentProps: {
      placeholder: '请输入字典码路径',
      clearable: true,
      disabled: true
    }
  },
  {
    field: 'parentId',
    label: '父节点',
    value: '0',
    component: 'Select',
    componentProps: {
      placeholder: '请选择父节点id',
      clearable: true,
      filterable: true,
      options: sysDictNameList
    }
  },
  {
    field: 'sort',
    label: '排序',
    value: '0',
    component: 'Input',
    componentProps: {
      placeholder: '请输入排序',
      clearable: true
    }
  },
  {
    field: 'remark',
    label: '字典说明',
    component: 'Input',
    componentProps: {
      placeholder: '请输入字典说明',
      clearable: true
    }
  },
  // [[ OnflowGenerator Range (- inputSchema -) End ]]
  {
    field: 'createTime',
    label: '创建时间',
    component: 'Input',
    remove: isAdd.value,
    componentProps: {
      placeholder: '暂无创建时间',
      disabled: true
    }
  },
  {
    field: 'updateTime',
    label: '更新时间',
    component: 'Input',
    remove: isAdd.value,
    componentProps: {
      placeholder: '暂无更新时间',
      disabled: true
    }
  },
  {
    field: 'createUserName',
    label: '创建人',
    component: 'Input',
    remove: isAdd.value,
    componentProps: {
      placeholder: '暂无创建人',
      disabled: true
    }
  },
  {
    field: 'updateUserName',
    label: '更新人',
    component: 'Input',
    remove: isAdd.value,
    componentProps: {
      placeholder: '暂无更新人',
      disabled: true
    }
  }
])

const rules = reactive({
  // [[ OnflowGenerator Range (- rules -) Start ]]
  code: [
    required(),
    {
      validator: (_, value, callback) => {
        if (isBlank(value)) {
          callback()
          return
        }
        if (value.length > 100) {
          callback(new Error('字典码不能超过100个字符'))
        } else {
          callback()
        }
      }
    }
  ],
  name: [
    required(),
    {
      validator: (_, value, callback) => {
        if (isBlank(value)) {
          callback()
          return
        }
        if (value.length > 100) {
          callback(new Error('字典值不能超过100个字符'))
        } else {
          callback()
        }
      }
    }
  ],
  parentId: [required()],
  sort: [required()],
  remark: [
    {
      validator: (_, value, callback) => {
        if (isBlank(value)) {
          callback()
          return
        }
        if (value.length > 500) {
          callback(new Error('字典说明不能超过500个字符'))
        } else {
          callback()
        }
      }
    }
  ]
  // [[ OnflowGenerator Range (- rules -) End ]]
})

const childrenSearch: SysDictSearchQo = {
  parentId: props.editId
}
const dictData = ref<Array<SysDictDetailVo>>([])
const refreshChildren = () => {
  sysDictChildrenListApi(childrenSearch).then((res) => {
    dictData.value = res.data as unknown as Array<SysDictDetailVo>
  })
}
refreshChildren()

// 编辑相关子字典
const showEditDictChildDialog = ref(false)
// 编辑时使用的对象
const editDictDetail = ref<SysDictEditQo>({
  id: 0,
  name: '',
  parentId: 0,
  code: '',
  remark: '',
  sort: 0
})

const addChild = () => {
  // 重置新增对象
  editDictDetail.value = {
    id: undefined,
    name: '',
    parentId: props.editId,
    code: '',
    remark: ''
  }
  showEditDictChildDialog.value = true
}

const editChild = (row: SysDictDetailVo) => {
  showEditDictChildDialog.value = true
  editDictDetail.value = { ...row }
}

const delChildRow = (row: SysDictDetailVo) => {
  ElMessageBox.confirm('是否要删除这条数据？', '删除警告', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning'
  }).then(() => {
    const deleteBo: BaseDeleteQo = {
      ids: [row.id]
    }
    sysDictDeleteApi(deleteBo).then(() => {
      refreshChildren()
    })
  })
}

const selectList = ref<Array<SysDictListVo>>([])
const selectionChange = (selectionList: Array<SysDictListVo>) => {
  selectList.value = selectionList
}

const delChildList = () => {
  ElMessageBox.confirm('是否要删除这些数据？', '删除警告', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning'
  }).then(() => {
    const rowIds = selectList.value.map((row) => {
      return row.id
    })
    const deleteBo: BaseDeleteQo = {
      ids: rowIds
    }
    sysDictDeleteApi(deleteBo).then(() => {
      refreshChildren()
    })
  })
}

const dialogLoading = ref(false)
const handleSaveEdit = () => {
  dialogLoading.value = true
  if (!editDictDetail.value.id) {
    sysDictAddApi(editDictDetail.value)
      .then(() => {
        refreshChildren()
        showEditDictChildDialog.value = false
        ElMessage.success('保存成功')
      })
      .finally(() => {
        dialogLoading.value = false
      })
  } else {
    sysDictUpdateApi(editDictDetail.value)
      .then(() => {
        refreshChildren()
        showEditDictChildDialog.value = false
        ElMessage.success('保存成功')
      })
      .finally(() => {
        dialogLoading.value = false
      })
  }
}

defineExpose({
  submit
})
</script>

<template>
  <Form :rules="rules" @register="formRegister" :schema="schema" ref="formRef" />

  <div v-if="!isAdd">
    <ElText type="primary" size="large" style="width: 100%">字典所属数据</ElText>
    <div style="display: block; margin-top: 20px">
      <ElButton type="primary" @click="addChild">新增</ElButton>
      <ElButton type="danger" @click="delChildList">删除</ElButton>
    </div>
    <ElTable :data="dictData" stripe style="width: 100%" @selection-change="selectionChange">
      <ElTableColumn type="selection" />
      <ElTableColumn label="字典码(数字/英文)" prop="code" />
      <ElTableColumn label="字典值" prop="name" />
      <ElTableColumn label="排序" prop="sort" />
      <ElTableColumn label="字典说明" prop="remark" />
      <ElTableColumn label="操作">
        <template #default="slot">
          <ElButton type="primary" size="small" @click="editChild(slot.row)">编辑</ElButton>
          <ElButton type="danger" size="small" @click="delChildRow(slot.row)">删除</ElButton>
        </template>
      </ElTableColumn>
    </ElTable>
  </div>

  <!-- 编辑字典项的对话框 -->
  <ElDialog v-model="showEditDictChildDialog" title="编辑字典项">
    <div>
      <ElInput v-model="editDictDetail.code" placeholder="字典码(数字/英文)" style="margin-bottom: 20px" />
      <ElInput v-model="editDictDetail.name" placeholder="字典值" style="margin-bottom: 20px" />
      <ElInput v-model="editDictDetail.sort" placeholder="排序" style="margin-bottom: 20px" />
      <ElInput v-model="editDictDetail.remark" placeholder="字典说明" />
    </div>
    <template #footer>
      <ElButton @click="showEditDictChildDialog = false">取消</ElButton>
      <ElButton type="primary" @click="handleSaveEdit" :loading="dialogLoading">保存</ElButton>
    </template>
  </ElDialog>
</template>
